<template>
	<!-- #ifndef APP-NVUE -->
	<view
	class="yingbing-flip"
	:prop="flipProp"
	:change:prop="flip.propWatcher"
	@touchstart="flip.touchstart"
	@touchmove="flip.touchmove"
	@touchend="flip.touchend"
	@touchcancel="flip.touchcancel"
	@mousedown="flip.mousedown"
	@mousemove="flip.mousemove"
	@mouseup="flip.mouseup"
	:style="{
		background: background
	}">
	<!-- #endif -->
	<!-- #ifdef APP-NVUE -->
	<view
	class="yingbing-flip"
	ref="yingbingFlip"
	@touchstart="fliptouchstart"
	@touchmove="fliptouchmove"
	@touchend="fliptouchend"
	:style="{
		background: background
	}">
	<!-- #endif -->
		<view
		class="yingbing-flip-item"
		:class="'yingbing-flip-item_' + item"
		v-for="(item, index) in dataSync"
		:ref="'yingbingFlipItem_' + item"
		:style="{
			'background': background,
			'transform': item > currentIndex ? translate + '(' + fullSize + ')' : item < currentIndex ? translate + '(-' + fullSize + ')' : ''
		}"
		:key="getKey(item)">
			<view
			class="yingbing-flip-item-content"
			:ref="'yingbingFlipItemContent_' + item"
			:class="'yingbing-flip-item-content_' + item"
			:style="{
				'background': background,
				'transform': item < currentIndex ? type == 'real' ?  translate + '(' + fullSize + ')' : translate + '(0)' : translate + '(0)'
			}">
				<!-- #ifdef MP -->
				<!-- 微信小程序vue2虽然支持在v-for中嵌套同名插槽，但会一直报错，引起页面卡顿，vue3不支持在v-for中嵌套同名插槽，所以增加2种微信小程序使用方式 -->
				<mp-child class="yingbing-flip-item-content" v-if="item > -1 && item < count && componentName" :item="data[item]" :index="item" :componentName="componentName"></mp-child>
				<slot v-if="item > -1 && item < count && !componentName" :name="'wx:' + item"></slot>
				<!-- #endif -->
				<!-- #ifndef MP -->
				<slot v-if="item > -1 && item < count" :item="data[item]" :index="item"></slot>
				<!-- #endif -->
			</view>
			<view
			class="yingbing-flip-item-bg"
			:ref="'yingbingFlipItemBg_' + item"
			:class="'yingbing-flip-item-bg_' + item"
			:style="{
				background: background,
				transform: item < currentIndex && type == 'real' ?  translate + '(0)' : translate + '(' + fullSize + ')',
			}"></view>
			<view
			class="yingbing-flip-item-shadow"
			:ref="'yingbingFlipItemShadow_' + item"
			:class="'yingbing-flip-item-shadow_' + item"
			:style="[shadowStyle]"></view>
		</view>
		<view class="yingbing-flip-pulldown"
		:style="[pulldownStyle]" v-if="pulldownable" ref="yingbing_flip_pulldown">
			<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-default" ref="yingbing_flip_pulldown_default">
				<slot name="pulldownDefault"></slot>
			</view>
			<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-ready" ref="yingbing_flip_pulldown_ready">
				<slot name="pulldownReady"></slot>
			</view>
			<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-loading" ref="yingbing_flip_pulldown_loading">
				<slot name="pulldownLoading"></slot>
			</view>
			<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-success" ref="yingbing_flip_pulldown_success">
				<slot name="pulldownSuccess"></slot>
			</view>
			<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-fail" ref="yingbing_flip_pulldown_fail">
				<slot name="pulldownFail"></slot>
			</view>
		</view>
		<view class="yingbing-flip-pullup"
		:style="[pullupStyle]" v-if="pullupable" ref="yingbing_flip_pullup">
			<view class="yingbing-flip-pullup-item yingbing-flip-pullup-default" ref="yingbing_flip_pullup_default">
				<slot name="pullupDefault"></slot>
			</view>
			<view class="yingbing-flip-pullup-item yingbing-flip-pullup-ready" ref="yingbing_flip_pullup_ready">
				<slot name="pullupReady"></slot>
			</view>
			<view class="yingbing-flip-pullup-item yingbing-flip-pullup-loading" ref="yingbing_flip_pullup_loading">
				<slot name="pullupLoading"></slot>
			</view>
			<view class="yingbing-flip-pullup-item yingbing-flip-pullup-success" ref="yingbing_flip_pullup_success">
				<slot name="pullupSuccess"></slot>
			</view>
			<view class="yingbing-flip-pullup-item yingbing-flip-pullup-fail" ref="yingbing_flip_pullup_fail">
				<slot name="pullupFail"></slot>
			</view>
		</view>
	</view>
</template>
<script>
	// #ifdef APP-NVUE
	import flipBindingx from './flip_bindingx.js'
	// #endif
	// #ifdef MP
	import MpChild from './mpChild.vue'
	// #endif
	export default {
		// #ifdef APP-NVUE
		mixins: [flipBindingx],
		// #endif
		// #ifdef MP
		components: {
			MpChild
		},
		// #endif
		props: {
			// #ifdef MP
			// 控制小程序子组件显示，传入组件名称则不使用插槽
			componentName: {
				type: String,
				default: ''
			},
			// #endif
			data: {
				type: Array,
				default () {
					return new Array
				}
			},
			//自动播放
			autoplay: {
				type: Boolean,
				default: false
			},
			//自动播放周期
			interval: {
				type: [Number, String],
				default: 5000
			},
			vertical: {
				type: Boolean,
				default: false
			},
			current: {
				type: [Number, String],
				default: 0
			},
			//翻页方式
			type: {
				type: String,
				default: 'real'
			},
			//滑动周期
			duration: {
				type: Number,
				default: 100
			},
			//容错距离
			sliderFault: {
				type: Number,
				default: 20
			},
			//背景颜色
			background: {
				type: String,
				default: '#fcd281'
			},
			//是否关闭点击左右2侧位置翻页
			unableClickPage: {
				type: Boolean,
				default: false
			},
			//开启下拉刷新
			pulldownable: {
				type: [Boolean, String],
				default: false
			},
			//下拉刷新高度
			pulldownHeight: {
				type: [Number, String],
				default: 80
			},
			//开启上拉加载
			pullupable: {
				type: Boolean,
				default: false
			},
			//上拉加载高度
			pullupHeight: {
				type: [Number, String],
				default: 80
			}
		},
		computed: {
			dataSync () {
				let arr = []
				if ( this.prevIndex >= 0 ) {
					arr.push(this.prevIndex)
				}
				arr.push(this.currentIndex)
				if ( this.nextIndex < this.count ) {
					arr.push(this.nextIndex)
				}
				return this.refreshing ? [] : arr.sort((a, b) => b-a)
			},
			nextIndex () {
				return this.currentIndex + 1 > this.count - 1 && this.count > 2 ? 0 : this.currentIndex + 1
			},
			prevIndex () {
				return this.currentIndex - 1 < 0 && this.count > 2 ? this.count - 1 : this.currentIndex - 1
			},
			count () {
				return this.data.length
			},
			flipProp () {
				return {
					vertical: this.vertical,
					pulldownable: this.pulldownable,
					pullupable: this.pullupable,
					pulldownHeight: this.pulldownHeight,
					pullupHeight: this.pullupHeight,
					loadingState: this.loadingState,
					duration: this.duration,
					unableClickPage: this.unableClickPage,
					nextIndex: this.nextIndex,
					prevIndex: this.prevIndex,
					currentIndex: this.currentIndex,
					type: this.type,
					count: this.count,
					flipTo: this.flipTo,
					sliderFault: this.sliderFault,
					translate: this.translate
				}
			},
			pulldownStyle () {
				return this.vertical ? {
					left: 0,
					right: 0,
					top: 0,
					height: this.pulldownHeight + 'px',
					transform: this.translate + '(-' + this.pulldownHeight + 'px)'
				} : {
					left: 0,
					top: 0,
					bottom: 0,
					width: this.pulldownHeight + 'px',
					transform: this.translate + '(-' + this.pulldownHeight + 'px)'
				}
			},
			pullupStyle () {
				return this.vertical ? {
					left: 0,
					right: 0,
					bottom: 0,
					height: this.pullupHeight + 'px',
					transform: this.translate + '(' + this.pullupHeight + 'px)'
				} : {
					right: 0,
					top: 0,
					bottom: 0,
					width: this.pullupHeight + 'px',
					transform: this.translate + '(' + this.pullupHeight + 'px)'
				}
			},
			shadowStyle () {
				return this.vertical ? {
					bottom: 0,
					right: 0,
					left: 0,
					height: 0,
					// #ifdef APP-NVUE
					'background-image': 'linear-gradient(to bottom, rgba(255,255,255, 0), rgba(0,0,0,.5))'
					// #endif
				} : {
					top: 0,
					bottom: 0,
					right: 0,
					width: 0,
					// #ifdef APP-NVUE
					'background-image': 'linear-gradient(to right, rgba(255,255,255, .1), rgba(0,0,0,.3))'
					// #endif
				}
			},
			translate () {
				return this.vertical ? 'translateY' : 'translateX'
			},
			fullSize () {
				return this.vertical ? '3050rpx' : '750rpx'
			}
		},
		data () {
			return {
				refreshing: false,
				currentIndex: 0,
				flipTo: 0,
				loadingState: '',
				updateIndex: null
			}
		},
		created() {
			this.currentIndex = this.current
			this.startAutoplay()
		},
		beforeDestroy() {
			this.stopAutoplay()
		},
		methods: {
			getKey (item) {
				// #ifdef APP-VUE
				return this.updateIndex == item ? item + this.data.length : item
				// #endif
				// #ifndef APP-VUE
				return item
				// #endif
			},
			forceUpdate (index) {
				this.updateIndex = index
				this.$nextTick(function () {
					this.updateIndex = null
				})
			},
			handleFlipChange (value) {
				this.startAutoplay()
				if ( value > 0 ) {
					this.currentIndex = this.currentIndex + value > this.count - 1 ? 0 : this.currentIndex + value
				} else {
					this.currentIndex = this.currentIndex + value < 0 ? this.count - 1 : this.currentIndex + value
				}
				this.$emit('change', {
					current: this.currentIndex,
					detail: this.data[this.currentIndex]
				})
				this.$emit('update:current', this.currentIndex)
			},
			pullingRefresh (type) {
				this.$emit(type, (state) => {
					this.loadingState = state
					// #ifdef APP-NVUE
					this.resetPullingBindingx()
					// #endif
				})
			},
			flipToNext () {
				this.stopAutoplay()
				// #ifdef APP-NVUE
				this.flipToNextBindingX()
				// #endif
				// #ifndef APP-NVUE
				this.flipTo = 0
				this.$nextTick(function () {
					this.flipTo = 1
				})
				// #endif
			},
			flipToPrev () {
				this.stopAutoplay()
				// #ifdef APP-NVUE
				this.flipToPrevBindingX()
				// #endif
				// #ifndef APP-NVUE
				this.flipTo = 0
				this.$nextTick(function () {
					this.flipTo = -1
				})
				// #endif
			},
			refresh () {
				this.stopAutoplay()
				this.refreshing = true
				this.$nextTick(function () {
					this.currentIndex = this.current
					this.refreshing = false
					this.startAutoplay()
				})
			},
			resetLoading () {
				this.loadingState = ''
				// #ifdef APP-NVUE
				this.resetPullingBindingx()
				// #endif
			},
			startAutoplay () {
				this.stopAutoplay()
				if ( this.autoplay ) {
					this.autoplayTimer = setTimeout(() => {
						if ( this.data.length > 1 && this.current < this.data.length - 1 ) this.flipToNext()
						else this.startAutoplay()
					}, this.interval)
				}
			},
			stopAutoplay () {
				if ( this.autoplayTimer ) {
					clearTimeout(this.autoplayTimer)
					this.autoplayTimer = null
				}
			}
		},
		watch: {
			current (newVal) {
				this.currentIndex = newVal
			},
			autoplay () {
				this.startAutoplay()
			}
		}
	}
</script>
<!-- #ifdef APP-VUE || H5 || MP-QQ || MP-WEIXIN -->
<script lang="wxs" module="flip" src="./flip.wxs"></script>
<!-- #endif -->
<style scoped>
	.yingbing-flip {
		/* #ifdef APP-NVUE */
		flex: 1;
		/* #endif */
		/* #ifndef APP-NVUE */
		height: 100%;
		/* #endif */
		overflow: hidden;
		position: relative;
	}
	.yingbing-flip-item {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		/* #ifndef APP-NVUE */
		overflow: hidden;
		/* #endif */
	}
	.yingbing-flip-item-content {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	.yingbing-flip-item-bg {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		/* #ifdef APP-NVUE */
		box-shadow: 0 0 20rpx rgba(0,0,0,0.2);
		/* #endif */
	}
	.yingbing-flip-item-shadow {
		position: absolute;
		/* #ifdef APP-NVUE */
		opacity: 0.5;
		/* #endif */
	}
	.yingbing-flip-pulldown, .yingbing-flip-pullup {
		position: absolute;
	}
	.yingbing-flip-pulldown-item, .yingbing-flip-pullup-item {
		/* #ifndef APP-NVUE */
		visibility: hidden;
		/* #endif */
		/* #ifdef APP-NVUE */
		opacity: 0;
		/* #endif */
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	/* #ifdef MP */
	/deep/ .scoped-ref {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	/deep/ yingbing-flip {
		display: block;
		height: 100%;
	}
	/* #endif */
</style>
